using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using WeifenLuo.WinFormsUI.Base;
using WeifenLuo.WinFormsUI.Security;

namespace HRM
{
    public partial class FormUserInfo : FormBaseData
    {
        private Ctrl_Security mCtrlScur;
        private string ms_UserID;
        private DataSet mdsUsers;
        private DataSet mdsUsersGroup;
        private DataView mUsersGroupsView;
        private DataRow mdrUsersGroup;
        private DataSet mdsGroups;
        private CurrencyManager mRowManagerDetail;

        public FormUserInfo()
        {
            InitializeComponent();
        }

        protected override void BasicForm_Load(object sender, EventArgs e)
        {
            ms_UserID = ((MainForm)MdiParent).ms_UserID;
            base.BasicForm_Load(sender, e);
            mMainForm.Refresh();
            this.WindowState = FormWindowState.Normal;
        }

        protected override void BaseForm_Activated(object sender, EventArgs e)
        {
            base.BaseForm_Activated(sender, e);
        }

        protected override void BasicForm_Closing(object sender, FormClosingEventArgs e)
        {
            base.BasicForm_Closing(sender, e);
        }

        protected override void BaseForm_KeyDown(object sender, KeyEventArgs e)
        {
            base.BaseForm_KeyDown(sender, e);
        }

        protected override void LoadMasterData()
        {
            lblStatus = lblstatus;
            btnOk = btnok;
            btnCancel = btncancel;
            mdsUsers = new DataSet();
            // Load into the Textboxes, and the List boxes
            mCtrlScur = new Ctrl_Security();
            // If User is not belong to the Admin group, he/she only sees his/her info
            if (mCtrlScur.InAdminGroup(ms_UserID))
                mdsUsers = mCtrlScur.GetAllUsers();
            else
                mdsUsers = mCtrlScur.GetUsers(ms_UserID);

            txtUserID.DataBindings.Add(new Binding("Text", mdsUsers.Tables[0], "ID_User"));
            txtFullName.DataBindings.Add(new Binding("Text", mdsUsers.Tables[0], "Full_Name"));
            txtDescription.DataBindings.Add(new Binding("Text", mdsUsers.Tables[0], "Description"));
            mRowManager = (CurrencyManager)txtUserID.BindingContext[mdsUsers.Tables[0]];

            SetData2List(mdsUsers);
            // Loading the user group
            LoadUserGroup();
            // Loading the available group
            mdsGroups = new DataSet();
            mdsGroups = mCtrlScur.GetGroups();
            lstAvailableGroups.DataSource = mdsGroups.Tables[0];
            lstAvailableGroups.DisplayMember = "ID_Group";

            SetReadOnly(true);
            base.LoadMasterData();
            // Make the RowMasterChanged to work.
            mRowManager.Position = 5;
            mRowManager.Position = 0;
        }

        // Load Groups contains current User into the Listbox
        private void LoadUserGroup()
        {	// Load user group depending on the user.
            mdsUsersGroup = new DataSet();
            mdsUsersGroup = mCtrlScur.GetUsersGroup(txtUserID.Text);
            mUsersGroupsView = mdsUsersGroup.Tables[0].DefaultView;

            mUsersGroupsView.Sort = "ID_GROUP";
            lstBelongGroups.DisplayMember = mUsersGroupsView.Sort;
            lstBelongGroups.Items.Clear();

            foreach (DataRowView lOV in mUsersGroupsView)
                lstBelongGroups.Items.Add(lOV);

            mRowManagerDetail = (CurrencyManager)lstBelongGroups.BindingContext[mUsersGroupsView];
            mRowManagerDetail.PositionChanged += new EventHandler(RowList_Changed);
            mRowManagerDetail.ItemChanged += new ItemChangedEventHandler(ItemList_Changed);
            if (mUsersGroupsView.Count > 0)
                mdrUsersGroup = mdsUsersGroup.Tables[0].Rows[0];
        }

        private void SetReadOnly(bool ab_switch)
        {
            txtPassword.ReadOnly = ab_switch;
            txtFullName.ReadOnly = ab_switch;
            txtDescription.ReadOnly = ab_switch;
        }

        private void RowList_Changed(object sender, System.EventArgs e)
        {	// if the currencymanager detects a positional event set the 'current' object for reference in delete method
            CurrencyManager CM = (CurrencyManager)sender;
            if (CM.Position != -1)
            {
                DataRowView Current = (DataRowView)CM.Current;
                mdrUsersGroup = Current.Row;
            }
        }

        private void ItemList_Changed(object sender, ItemChangedEventArgs e)
        {	// if the currencymanager detects a value change event show the new details in the form controls
            CurrencyManager CM = (CurrencyManager)sender;
            if (CM.Position != -1)
            {
                DataRowView Current = (DataRowView)CM.Current;
                mdrUsersGroup = Current.Row;
            }
        }

        private void btncancel_Click(object sender, System.EventArgs e)
        {
            cancel();
        }

        private void btnok_Click(object sender, System.EventArgs e)
        {
            save();
        }

        private void lstBelongGroups_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            mRowManagerDetail.Position = lstBelongGroups.SelectedIndex;
        }

        private void btnRemove_Click(object sender, System.EventArgs e)
        {
            if (!btnRemove.Enabled || lstBelongGroups.SelectedItem == null) return;
            try
            {
                if (mdsUsersGroup.Tables[0].Rows.Count == 0)
                {
                    btnRemove.Enabled = false;
                    return;
                }
                mRowManagerDetail.EndCurrentEdit();
                DataRow ldrUsersGroups = mdrUsersGroup;
                ldrUsersGroups.Delete();
                lstBelongGroups.Items.RemoveAt(lstBelongGroups.SelectedIndex);
                btnAdd.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnAdd_Click(object sender, System.EventArgs e)
        {	// Adding the group that this user is belong to.
            if (!btnAdd.Enabled || lstAvailableGroups.SelectedItem == null) return;
            try
            {
                DataRow ldrGroups = mdsGroups.Tables[0].Rows[lstAvailableGroups.SelectedIndex];
                DataRow ldrUsersGroups;
                // If the Group is existing in the List --> do nothing
                for (int li_index = 0; li_index < mUsersGroupsView.Count; li_index++)
                {
                    DataRowView opv = mUsersGroupsView[li_index];
                    ldrUsersGroups = opv.Row;
                    if (ldrGroups["ID_Group"].ToString() == ldrUsersGroups["ID_Group"].ToString()) return;
                }
                // The Group is not existing in the List --> add the Group to the List/UsersGroupsSet
                mRowManagerDetail.EndCurrentEdit();
                mRowManagerDetail.AddNew();
                mRowManagerDetail.Position = mRowManagerDetail.Count - 1;
                ldrUsersGroups = mdsUsersGroup.Tables[0].Rows[mRowManagerDetail.Position];
                ldrUsersGroups["ID_Group"] = ldrGroups["ID_Group"];
                ldrUsersGroups["ID_User"] = txtUserID.Text.Trim();
                lstBelongGroups.Items.Add(ldrGroups["ID_Group"]);
                btnRemove.Enabled = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public override void modify()
        {	// The Administrator cannot change Developer's information.
            if (ms_UserID == "ADMINISTRATOR" && txtUserID.Text == "DEVELOPER")
            {
                MessageBox.Show("The DEVELOPER's info cannot be modified.", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            if (mMainForm.mUserRight.IsInAdminGroup(mMainForm.ms_UserID))
            {	// Only modify the In used when the user is blocked and 
                // the system is crashed 
                btnAdd.Enabled = true;
                btnRemove.Enabled = true;
                SetReadOnly(true);
            }
            else
            {
                btnAdd.Enabled = false;
                btnRemove.Enabled = false;
            }
            SetReadOnly(false);
            //this.mFormRight = mMainForm.mUserRight.GetAccess("FormChangePassword"); // temp comment
            if (this.mFormRight.mb_read)
            {
                btnChangePassword.Visible = true;
                txtPassword.Visible = false;
            }
            else
            {
                btnChangePassword.Visible = false;
                txtPassword.Visible = true;
                txtPassword.Enabled = false;
            }
            base.modify();
        }

        public override void add()
        {
            base.add();
            txtUserID.Focus();
            txtUserID.ReadOnly = false;
            btnChangePassword.Visible = false;
            txtPassword.Visible = true;
            SetReadOnly(false);
            // cannot Add/Remove Group in the ADD mode.
            btnAdd.Enabled = false;
            btnRemove.Enabled = false;
            mRowManager.EndCurrentEdit();
            mRowManager.AddNew();
            //mdsUsers.Tables[0].NewRow();
            txtPassword.Text = "";
        }

        public override void delete()
        {	// Check the the user (A) whether is is belong to any group
            //		If the user wouldn't belong to any group 
            //			--> show the confirm message (call base.delete())
            //			If the actor say yes --> delete it.
            //		Else (the user is belong to at least one group)
            //			Show message to info the actor

            if (txtUserID.Text == ms_UserID)
            {// The current user cannot be deleted.
                MessageBox.Show("Cannot delete the current logged in user.", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (txtUserID.Text == "ADMINISTRATOR")
            {// User Admin cannot be deleted
                MessageBox.Show("Cannot delete the Administrator.", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (lstBelongGroups.Items.Count > 0)
            {// Cannot delete this user. We must delete all the groups that containt this user.
                MessageBox.Show("All the groups that containt this user must be deleted.", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            base.delete();
            if (!mb_AcceptDelete) return; // confirm delete
            mRowManager.EndCurrentEdit();
            DataRow ldrUsers = mdsUsers.Tables[0].Rows[mRowManager.Position];
            ldrUsers.Delete();

            string ls_NotNullCol, ls_tableName;
            string ls_errorMsg = mCtrlScur.Update(mdsUsers, out ls_NotNullCol, out ls_tableName);
            if (ls_errorMsg != "")
            {
                if (ls_NotNullCol != "" || ls_tableName != "")
                {
                    string[] lsa_param = { ls_NotNullCol, ls_tableName };
                    MessageBox.Show(lsa_param[0] + " cannot be empty", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                    MessageBox.Show("DB Error ", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                mRowManager.Position = mdsUsers.Tables[0].Rows.Count - 1;
                return;
            }
            LoadUserGroup();
            base.post_delete();
        }

        public override void cancel()
        {
            SetReadOnly(true);
            txtUserID.ReadOnly = true;
            btnAdd.Enabled = false;
            btnRemove.Enabled = false;
            btnChangePassword.Visible = false;
            txtPassword.Visible = true;
            mRowManager.CancelCurrentEdit();
            mdsUsers.RejectChanges();
            LoadUserGroup();
            base.cancel();
        }

        public override void save()
        {
            mRowManager.EndCurrentEdit();
            switch (GetCurrentAction())
            {
                case MODES.ADD:
                    // Check the user has password yet? or has been confirmed yet?
                    if (txtPassword.Text == null || txtPassword.Text == "")
                    {
                        MessageBox.Show("Missing Or Unconfirmed Password", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return;
                    }

                    DataRow ldrUsers = mdsUsers.Tables[0].Rows[mRowManager.Position];
                    // Encrypt the password b4 saving to the database
                    ldrUsers["Password"] = mCtrlScur.EncryptPassword("123"); //txtPassword.Text

                    // Prepare for the group that the newer will be belong.
                    DataRow ldrUsersGroup;
                    for (int i = 0; i < lstBelongGroups.Items.Count; i++)
                    {
                        ldrUsersGroup = mdsUsersGroup.Tables[0].Rows[i];
                        ldrUsersGroup["UpdateTime"] = DateTime.Now;
                    }
                    break;

                case MODES.MODIFY:
                    txtPassword.Text = "admin";
                    break;
            }

            // Update the user's info to the database
            string ls_NotNullCol, ls_tableName;
            string ls_errorMsg = mCtrlScur.Update(mdsUsers, out ls_NotNullCol, out ls_tableName);
            if (ls_errorMsg != "")
            {
                if (ls_NotNullCol != "" || ls_tableName != "")
                {
                    string[] lsa_param = { ls_NotNullCol, ls_tableName };
                    MessageBox.Show(lsa_param[0] + " cannot be empty", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                    MessageBox.Show("DB Error", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Update the groups that newer belong to.
            ls_errorMsg = mCtrlScur.UpdateUsersGroup(mdsUsersGroup, out ls_NotNullCol, out ls_tableName);
            if (ls_errorMsg != "")
            {
                if (ls_NotNullCol != "" || ls_tableName != "")
                {
                    string[] lsa_param = { ls_NotNullCol, ls_tableName };
                    MessageBox.Show(lsa_param[0] + " cannot be empty", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                else
                    MessageBox.Show("DB Error", ConstantKeys.Title, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            SetReadOnly(true);
            txtUserID.ReadOnly = true;
            btnAdd.Enabled = false;
            btnRemove.Enabled = false;
            btnChangePassword.Visible = false;
            txtPassword.Visible = true;
            base.save();
        }

        public override void RowMaster_Changed(object sender, EventArgs e)
        {
            base.RowMaster_Changed(sender, e);
            LoadUserGroup();
            if (GetCurrentAction() == MODES.FULL)  txtPassword.Text = "admin";
        }

    }
}